from fastapi import APIRouter, HTTPException, Depends, Query
from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field
from datetime import datetime
from service.sleep_monitoring_service import SleepMonitoringService
from service.room_service import RoomService
from controller.base_controller import BaseController


class SessionResponse(BaseModel):
    """会话响应模型"""
    session_id: str
    room_id: str
    start_time: datetime
    end_time: datetime
    total_seconds: int
    dominant_state: Optional[str]
    avg_confidence: Optional[float]
    deep_sleep_duration: Optional[int]
    light_sleep_duration: Optional[int]
    awake_duration: Optional[int]
    description: Optional[str]
    created_at: datetime
    updated_at: datetime


class SessionAnalysisResponse(BaseModel):
    """会话分析响应模型"""
    session_info: Dict[str, Any]
    summary: Dict[str, Any]
    brainwave_data: Dict[str, Any]
    brainwave_stats: Optional[Dict[str, Any]] = None


class RoomStatisticsResponse(BaseModel):
    """房间统计响应模型"""
    room_id: str
    period_days: int
    total_sessions: int
    total_duration_seconds: int
    avg_duration_seconds: float
    state_distribution: Dict[str, int]
    avg_confidence: Optional[float]
    first_session: Optional[datetime]
    last_session: Optional[datetime]


class UpdateDescriptionRequest(BaseModel):
    """更新描述请求模型"""
    description: str = Field(..., max_length=1000, description="治疗师描述")


class SleepMonitoringController(BaseController):
    """睡眠监测控制器"""
    
    def __init__(self):
        super().__init__()
        self.router = APIRouter(prefix="/api/monitoring", tags=["睡眠监测"])
        self.sleep_service = SleepMonitoringService()
        self.room_service = RoomService()
        self._register_routes()
    
    def _register_routes(self):
        """注册路由"""
        
        @self.router.post("/sessions/{room_id}", response_model=SessionResponse, summary="创建监测会话")
        async def create_session(room_id: str):
            """
            为指定房间创建新的监测会话
            
            - **room_id**: 房间唯一标识符
            """
            # 验证房间权限
            if not await self.room_service.validate_room_access(room_id):
                raise HTTPException(status_code=403, detail="房间无访问权限或不存在")
            
            try:
                session = await self.sleep_service.create_session(room_id)
                return SessionResponse(
                    session_id=session.session_id,
                    room_id=session.room_id,
                    start_time=session.start_time,
                    end_time=session.end_time,
                    total_seconds=session.total_seconds,
                    dominant_state=session.dominant_state,
                    avg_confidence=float(session.avg_confidence) if session.avg_confidence else None,
                    deep_sleep_duration=session.deep_sleep_duration,
                    light_sleep_duration=session.light_sleep_duration,
                    awake_duration=session.awake_duration,
                    description=session.description,
                    created_at=session.created_at,
                    updated_at=session.updated_at
                )
            except Exception as e:
                raise HTTPException(status_code=500, detail=f"创建会话失败: {str(e)}")
        
        @self.router.post("/sessions/{session_id}/end", response_model=SessionResponse, summary="结束监测会话")
        async def end_session(session_id: str):
            """
            结束指定的监测会话
            
            - **session_id**: 会话唯一标识符
            """
            session = await self.sleep_service.end_session(session_id)
            if not session:
                raise HTTPException(status_code=404, detail="会话不存在")
            
            return SessionResponse(
                session_id=session.session_id,
                room_id=session.room_id,
                start_time=session.start_time,
                end_time=session.end_time,
                total_seconds=session.total_seconds,
                dominant_state=session.dominant_state,
                avg_confidence=float(session.avg_confidence) if session.avg_confidence else None,
                deep_sleep_duration=session.deep_sleep_duration,
                light_sleep_duration=session.light_sleep_duration,
                awake_duration=session.awake_duration,
                description=session.description,
                created_at=session.created_at,
                updated_at=session.updated_at
            )
        
        @self.router.get("/sessions/{session_id}", response_model=SessionResponse, summary="获取会话详情")
        async def get_session(session_id: str):
            """
            获取指定会话的详细信息
            
            - **session_id**: 会话唯一标识符
            """
            session = await self.sleep_service.get_session_by_id(session_id)
            if not session:
                raise HTTPException(status_code=404, detail="会话不存在")
            
            return SessionResponse(
                session_id=session.session_id,
                room_id=session.room_id,
                start_time=session.start_time,
                end_time=session.end_time,
                total_seconds=session.total_seconds,
                dominant_state=session.dominant_state,
                avg_confidence=float(session.avg_confidence) if session.avg_confidence else None,
                deep_sleep_duration=session.deep_sleep_duration,
                light_sleep_duration=session.light_sleep_duration,
                awake_duration=session.awake_duration,
                description=session.description,
                created_at=session.created_at,
                updated_at=session.updated_at
            )
        
        @self.router.get("/rooms/{room_id}/sessions", response_model=List[SessionResponse], summary="获取房间会话列表")
        async def get_room_sessions(
            room_id: str,
            limit: int = Query(50, ge=1, le=100, description="返回数量限制"),
            offset: int = Query(0, ge=0, description="偏移量")):
            """
            获取指定房间的监测会话列表
            
            - **room_id**: 房间唯一标识符
            - **limit**: 返回数量限制（1-100）
            - **offset**: 偏移量
            """
            # 验证房间权限
            if not await self.room_service.validate_room_access(room_id):
                raise HTTPException(status_code=403, detail="房间无访问权限或不存在")
            
            try:
                sessions = await self.sleep_service.get_room_sessions(room_id, limit, offset)
                return [
                    SessionResponse(
                        session_id=session.session_id,
                        room_id=session.room_id,
                        start_time=session.start_time,
                        end_time=session.end_time,
                        total_seconds=session.total_seconds,
                        dominant_state=session.dominant_state,
                        avg_confidence=float(session.avg_confidence) if session.avg_confidence else None,
                        deep_sleep_duration=session.deep_sleep_duration,
                        light_sleep_duration=session.light_sleep_duration,
                        awake_duration=session.awake_duration,
                        description=session.description,
                        created_at=session.created_at,
                        updated_at=session.updated_at
                    )
                    for session in sessions
                ]
            except Exception as e:
                raise HTTPException(status_code=500, detail=f"获取会话列表失败: {str(e)}")
        
        @self.router.get("/sessions/{session_id}/analysis", response_model=SessionAnalysisResponse, summary="获取会话分析")
        async def get_session_analysis(session_id: str):
            """
            获取指定会话的详细分析数据
            
            包括脑波数据、状态分析、统计信息等
            
            - **session_id**: 会话唯一标识符
            """
            analysis = await self.sleep_service.get_session_analysis(session_id)
            if not analysis:
                raise HTTPException(status_code=404, detail="会话不存在")
            
            return SessionAnalysisResponse(**analysis)
        
        @self.router.put("/sessions/{session_id}/description", summary="更新会话描述")
        async def update_session_description(session_id: str, request: UpdateDescriptionRequest):
            """
            更新会话的治疗师描述
            
            - **session_id**: 会话唯一标识符
            - **description**: 治疗师描述内容
            """
            success = await self.sleep_service.update_session_description(session_id, request.description)
            if not success:
                raise HTTPException(status_code=404, detail="会话不存在")
            
            return {"message": "描述更新成功", "session_id": session_id}
        
        @self.router.delete("/sessions/{session_id}", summary="删除会话")
        async def delete_session(session_id: str):
            """
            删除指定的监测会话
            
            注意：此操作将同时删除所有关联的原始数据
            
            - **session_id**: 会话唯一标识符
            """
            success = await self.sleep_service.delete_session(session_id)
            if not success:
                raise HTTPException(status_code=404, detail="会话不存在")
            
            return {"message": "会话删除成功", "session_id": session_id}
        
        @self.router.get("/rooms/{room_id}/statistics", response_model=RoomStatisticsResponse, summary="获取房间统计")
        async def get_room_statistics(
            room_id: str,
            days: int = Query(30, ge=1, le=365, description="统计天数")):
            """
            获取指定房间的统计信息
            
            - **room_id**: 房间唯一标识符
            - **days**: 统计天数（1-365天）
            """
            # 验证房间权限
            if not await self.room_service.validate_room_access(room_id):
                raise HTTPException(status_code=403, detail="房间无访问权限或不存在")
            
            try:
                stats = await self.sleep_service.get_room_statistics(room_id, days)
                return RoomStatisticsResponse(**stats)
            except Exception as e:
                raise HTTPException(status_code=500, detail=f"获取统计信息失败: {str(e)}")
        
        @self.router.get("/sessions/{session_id}/brainwave-data", summary="获取脑波数据")
        async def get_brainwave_data(
            session_id: str,
            wave_type: Optional[str] = Query(None, description="脑波类型 (delta, theta, alpha, beta, gamma)"),
            start_time: Optional[int] = Query(None, description="开始时间戳"),
            end_time: Optional[int] = Query(None, description="结束时间戳")):
            """
            获取会话的脑波数据
            
            - **session_id**: 会话唯一标识符
            - **wave_type**: 指定脑波类型，不指定则返回所有类型
            - **start_time**: 开始时间戳，用于数据过滤
            - **end_time**: 结束时间戳，用于数据过滤
            """
            session = await self.sleep_service.get_session_by_id(session_id)
            if not session:
                raise HTTPException(status_code=404, detail="会话不存在")
            
            # 获取所有脑波数据
            brainwave_data = session.get_all_brainwave_data()
            
            # 过滤指定的脑波类型
            if wave_type:
                if wave_type not in ['delta', 'theta', 'alpha', 'beta', 'gamma']:
                    raise HTTPException(status_code=400, detail="无效的脑波类型")
                
                wave_key = f"{wave_type}_ratio"
                if wave_key in brainwave_data:
                    brainwave_data = {wave_key: brainwave_data[wave_key]}
                else:
                    brainwave_data = {}
            
            # 时间过滤
            if start_time is not None or end_time is not None:
                filtered_data = {}
                for key, data in brainwave_data.items():
                    if isinstance(data, list):
                        filtered_points = []
                        for timestamp, value in data:
                            if start_time is not None and timestamp < start_time:
                                continue
                            if end_time is not None and timestamp > end_time:
                                continue
                            filtered_points.append([timestamp, value])
                        filtered_data[key] = filtered_points
                    else:
                        filtered_data[key] = data
                brainwave_data = filtered_data
            
            return {
                "session_id": session_id,
                "brainwave_data": brainwave_data,
                "data_points": sum(len(data) if isinstance(data, list) else 0 for data in brainwave_data.values())
            }
        
        @self.router.get("/sessions/{session_id}/export", summary="导出会话数据")
        async def export_session_data(
            session_id: str,
            format: str = Query("json", description="导出格式 (json, csv)")):
            """
            导出会话数据
            
            - **session_id**: 会话唯一标识符
            - **format**: 导出格式（json 或 csv）
            """
            if format not in ['json', 'csv']:
                raise HTTPException(status_code=400, detail="不支持的导出格式")
            
            analysis = await self.sleep_service.get_session_analysis(session_id)
            if not analysis:
                raise HTTPException(status_code=404, detail="会话不存在")
            
            if format == 'json':
                return analysis
            elif format == 'csv':
                # 简化的CSV导出（实际项目中可能需要更复杂的CSV处理）
                from fastapi.responses import PlainTextResponse
                
                csv_content = "timestamp,state,confidence,delta,theta,alpha,beta,gamma\n"
                
                # 获取所有数据点
                brainwave_data = analysis.get('brainwave_data', {})
                states = brainwave_data.get('states', [])
                confidence = brainwave_data.get('confidence', [])
                delta = brainwave_data.get('delta_ratio', [])
                theta = brainwave_data.get('theta_ratio', [])
                alpha = brainwave_data.get('alpha_ratio', [])
                beta = brainwave_data.get('beta_ratio', [])
                gamma = brainwave_data.get('gamma_ratio', [])
                
                # 创建时间戳索引
                timestamps = set()
                for data_list in [states, confidence, delta, theta, alpha, beta, gamma]:
                    for timestamp, _ in data_list:
                        timestamps.add(timestamp)
                
                # 为每个时间戳生成CSV行
                for ts in sorted(timestamps):
                    row_data = [str(ts)]
                    
                    # 查找每个数据类型在该时间戳的值
                    for data_list in [states, confidence, delta, theta, alpha, beta, gamma]:
                        value = ""
                        for timestamp, val in data_list:
                            if timestamp == ts:
                                value = str(val)
                                break
                        row_data.append(value)
                    
                    csv_content += ",".join(row_data) + "\n"
                
                return PlainTextResponse(
                    content=csv_content,
                    media_type="text/csv",
                    headers={"Content-Disposition": f"attachment; filename=session_{session_id}.csv"}
                )